#include "slepdef.h"
#include <string.h>
#include <stdlib.h>

slep_matrix* createCSCSlepMatrix(int m, int n, double *values, int *rows, int *columnIndex){
	slep_matrix* mtrx = (slep_matrix*) malloc( sizeof(slep_matrix) );
	mtrx->sparsity = SlepSparse;
	mtrx->m = m;
	mtrx->n = n;
	mtrx->data.spmtrx.format = SlepCompressedSparseColumn;
	mtrx->data.spmtrx.values = values;
	mtrx->data.spmtrx.Index = columnIndex;
	mtrx->data.spmtrx.ColumnsORRows = rows;
	return mtrx;
}

slep_matrix* createCSRSlepMatrix(int m, int n, double *values, int *columns, int *rowIndex){
	slep_matrix* mtrx = (slep_matrix*) malloc( sizeof(slep_matrix) );
	mtrx->sparsity = SlepSparse;
	mtrx->m = m;
	mtrx->n = n;
	mtrx->data.spmtrx.format = SlepCompressedSparseRow;
	mtrx->data.spmtrx.values = values;
	mtrx->data.spmtrx.Index = rowIndex;
	mtrx->data.spmtrx.ColumnsORRows = columns;
	return mtrx;
}

slep_matrix* createDenseSlepMatrix(int m, int ld, int n, double *values){
	slep_matrix *mtrx = (slep_matrix*) malloc(sizeof(slep_matrix));
	mtrx->sparsity = SlepDense;
	mtrx->uplobanded = SlepFull;
	mtrx->m = m;
	mtrx->ld = ld;
	mtrx->n = n;
	mtrx->data.mtrx = values;
	return mtrx;
}

slep_matrix* createSymmetricSlepMatrix(int n, double *values, slep_uplobanded uplobanded, int bandwidth){
	slep_matrix *mtrx;
	mtrx = (slep_matrix*) malloc(sizeof(slep_matrix));
	mtrx->sparsity = SlepSymmetric;
	mtrx->m = n;
	mtrx->n = n;
	mtrx->data.mtrx = values;

	mtrx->uplobanded = uplobanded;
	if(uplobanded == SlepBandedLower)
		mtrx->kl = bandwidth;
	else if(uplobanded == SlepBandedUpper)
		mtrx->ku = bandwidth;
	return mtrx;
}


slep_matrix* createTriangularSlepMatrix(int n, double *values, slep_uplobanded uplobanded, int bandwidth){
	slep_matrix *mtrx;
	mtrx = (slep_matrix*) malloc(sizeof(slep_matrix));
	mtrx->sparsity = SlepTriangular;
	mtrx->m = n;
	mtrx->n = n;
	mtrx->data.mtrx = values;

	mtrx->uplobanded = uplobanded;
	if(uplobanded == SlepBandedLower)
		mtrx->kl = bandwidth;
	else if(uplobanded == SlepBandedUpper)
		mtrx->ku = bandwidth;
	return mtrx;
}

slep_vector* createSparseSlepVector(int nnz, int *index, double *values){
	slep_vector *vctr = (slep_vector*) malloc(sizeof(slep_vector));
	vctr->dim = index[nnz-1] + 1;
	vctr->sparsity = SlepSparse;
	vctr->data.spvctr.nnz = nnz;
	vctr->data.spvctr.index = index;
	vctr->data.spvctr.values = values;
	return vctr;
}

slep_vector* createDenseSlepVector(int dimension, double *values, int inc){
	slep_vector *vctr = (slep_vector*) malloc( sizeof(slep_vector));
	vctr->dim = dimension;
	vctr->sparsity = SlepDense;
	vctr->data.vctr = values;
	vctr->inc = inc;
	return vctr;
}



int slepFreeVector(slep_vector* vctr){
	if(vctr->sparsity == SlepSparse){
		if(vctr->data.spvctr.nnz != 0){
			if(vctr->data.spvctr.values != NULL)
				free(vctr->data.spvctr.values);
			if(vctr->data.spvctr.index != NULL)
				free(vctr->data.spvctr.index);
		}
		free(vctr);
		return 0;
	}else if (vctr->sparsity == SlepDense){
		if(vctr->data.vctr != NULL)
			free(vctr->data.vctr);
		free(vctr);
		return 0;
	}
	return 1;
}



int slepFreeMatrix(slep_matrix* mtrx){
	if( mtrx->sparsity == SlepSparse){
		if(mtrx->data.spmtrx.ColumnsORRows != NULL)
			free( mtrx->data.spmtrx.ColumnsORRows);
		if(mtrx->data.spmtrx.Index != NULL)
			free( mtrx->data.spmtrx.Index);
		if(mtrx->data.spmtrx.values != NULL)
			free( mtrx->data.spmtrx.values);
		free(mtrx);
		return 0;
	} else if( mtrx->sparsity == SlepDense ){
		if( mtrx->data.mtrx != NULL)
			free( mtrx->data.mtrx );
		free(mtrx);
		return 0;
	}
	return 1;
}

int findNnz(slep_matrix* mtrx){
	if(mtrx->sparsity != SlepSparse)
		return -1;
	if(mtrx->data.spmtrx.format == SlepCompressedSparseColumn)
		return mtrx->data.spmtrx.Index[mtrx->n];
	else if(mtrx->data.spmtrx.format == SlepCompressedSparseRow)
		return mtrx->data.spmtrx.Index[mtrx->m];
	return 0;
}


